import { defineStore } from 'pinia';
import { ErrorMessageMode } from '/#/axios';
import {
  addAttributesParams,
  addCategoryParams,
  addProductParams,
  deleteAttributesParams,
  getCategoriesParams,
  getCategoryAttributesParams,
  getSingleAttributeParams,
  updateAttributesParams,
  updateCategoryParams,
  updateProductParams,
} from '/@/api/shopper/model/shopGoodsModel';
import {
  addAttributesApi,
  addCategoryApi,
  addShopProductApi,
  deleteAttributesApi,
  deleteCategoryApi,
  deleteSingleProductApi,
  getCategoriesApi,
  getCategoryAttributesApi,
  getSingleAttributeApi,
  getSingleProductApi,
  shopProductApi,
  updateAttributesApi,
  updateCategoryApi,
  updateSingleProductApi,
  uploadApi,
} from '/@/api/shopper/shopGoodsApi';

interface stateModel {
  query: string;
  pagination: object | any;
  singleProduct: object | any;
  categories: object[] | any;
  secondLevel: object[] | any;
  attributeList: object[];
}

export const useShopGoodsStore = defineStore({
  id: 'shop-goods',
  state: (): stateModel => ({
    query: '',
    pagination: {
      current: 1,
      pageSize: 10,
      total: 0,
    },
    singleProduct: {},
    categories: [],
    secondLevel: [],
    attributeList: [],
  }),
  getters: {},
  actions: {
    /**
     * @description: get product list
     */
    async getProductList(params: { mode?: ErrorMessageMode }): Promise<Object[] | any> {
      try {
        const { mode } = params;
        const data = await shopProductApi(
          {
            pagenum: this.pagination.current,
            pagesize: this.pagination.pageSize,
            query: this.query,
          },
          mode,
        );
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: add product
     */
    async addProduct(
      params: addProductParams & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, ...addProductParams } = params;
        const data = await addShopProductApi(addProductParams, mode);
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: get categories list
     */
    async getCategoryList(
      params: getCategoriesParams & { mode?: ErrorMessageMode },
    ): Promise<Object[] | any> {
      try {
        const { mode, ...getCategoriesParams } = params;
        const data = await getCategoriesApi(getCategoriesParams, mode);
        const { resultType, type } = getCategoriesParams;
        if (resultType == 'tree') {
          function dfs_getCategory(data: object[]): any {
            const result = data.map((item: any) => {
              const temp: object | any = {
                value: item.cat_id,
                label: item.cat_name,
              };
              if (item.children) {
                temp.children = dfs_getCategory(item.children);
              }
              return temp;
            });
            return result;
          }
          const treeList = dfs_getCategory(data);
          if (type) {
            this.secondLevel = treeList;
          } else {
            this.categories = treeList;
          }
          return treeList;
        }
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: add category
     */
    async addCategory(params: addCategoryParams & { mode?: ErrorMessageMode }): Promise<object> {
      try {
        const { mode, ...addCategoryParams } = params;
        const data = await addCategoryApi(addCategoryParams, mode);
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: delete category
     */
    async deleteCategory(params: { id: number; mode?: ErrorMessageMode }): Promise<void> {
      try {
        const { mode, id } = params;
        await deleteCategoryApi({ id }, mode);
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: update category
     */
    async updateCategory(
      params: updateCategoryParams & { mode?: ErrorMessageMode },
    ): Promise<void> {
      try {
        const { mode, ...updateCategoryParams } = params;
        const data = await updateCategoryApi(updateCategoryParams, mode);
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: get category attributes list
     */
    async getCategoryAttributeList(
      params: getCategoryAttributesParams & { mode?: ErrorMessageMode },
    ): Promise<Object[] | any> {
      try {
        const { mode, ...getCategoryAttributesParams } = params;
        const data = await getCategoryAttributesApi(getCategoryAttributesParams, mode);
        data.forEach((item: any) => {
          if (getCategoryAttributesParams.sel == 'many') {
            item.attr_vals = item.attr_vals.length ? item.attr_vals.split(',') : [];
          }
          if (getCategoryAttributesParams.sel == 'only') {
            item.attr_vals = item.attr_vals.length ? item.attr_vals.split(' ') : [];
          }
        });
        this.attributeList = data;
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: upload image list
     */
    async upload(
      params: { file: string | Blob } & { mode?: ErrorMessageMode },
      callback: Fn,
    ): Promise<Object[] | any> {
      try {
        const { mode, file } = params;
        const formData = new FormData();
        formData.append('file', file);
        const data = await uploadApi(formData, mode, callback);
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: get single product
     */
    async getSingleProduct(
      params: { id: number } & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, id } = params;
        const data = await getSingleProductApi({ id }, mode);
        const {
          goods_id,
          goods_name,
          goods_price,
          goods_number,
          goods_weight,
          goods_cat,
          goods_introduce,
          pics,
          attrs,
        } = data;
        const parameterValue: object[] = [];
        const attributesValue: object[] = [];
        attrs.map((item: any) => {
          if (item.attr_sel == 'many') {
            item.attr_vals = item.attr_vals.length > 0 ? item.attr_vals.split(',') : [];
            item.attr_value = item.attr_value.length > 0 ? item.attr_value.split(',') : [];
            parameterValue.push(item);
          }
          if (item.attr_sel == 'only') {
            const attributesItem = {
              field: item.attr_id,
              component: 'Input',
              label: item.attr_name,
              defaultValue: item.attr_value,
            };
            attributesValue.push(attributesItem);
          }
        });
        const categories = goods_cat.split(',');
        const result = {
          goods_id,
          goods_name,
          goods_price,
          goods_number,
          goods_weight,
          goods_cat: categories,
          goods_introduce,
          pics,
          parameterValue,
          attributesValue,
        };
        this.singleProduct = result;
        return result;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: update product
     */
    async updateProduct(
      params: updateProductParams & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, ...updateProductParams } = params;
        const data = await updateSingleProductApi(updateProductParams, mode);
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: delete single product
     */
    async deleteSingleProduct(
      params: { id: number } & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, id } = params;
        const data = await deleteSingleProductApi({ id }, mode);
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: add attributes
     */
    async addAttributes(
      params: addAttributesParams & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, ...addAttributesParams } = params;
        const data = await addAttributesApi(addAttributesParams, mode);
        if (!Array.isArray(data.attr_vals)) {
          if (addAttributesParams.attr_sel == 'many') {
            data.attr_vals = data.attr_vals.split(',');
          }
          if (addAttributesParams.attr_sel == 'only') {
            data.attr_vals = data.attr_vals.split(' ');
          }
        }
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: update attributes
     */
    async updateAttributes(
      params: updateAttributesParams & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, ...updateAttributesParams } = params;
        const data = await updateAttributesApi(updateAttributesParams, mode);
        if (!Array.isArray(data.attr_vals)) {
          if (updateAttributesParams.attr_sel == 'many') {
            data.attr_vals = data.attr_vals.length ? data.attr_vals.split(',') : [];
          }
          if (updateAttributesParams.attr_sel == 'many') {
            data.attr_vals = data.attr_vals.length ? data.attr_vals.split(' ') : [];
          }
        }
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: get single attribute
     */
    async getSingleAttribute(
      params: getSingleAttributeParams & { mode?: ErrorMessageMode },
    ): Promise<Object | any> {
      try {
        const { mode, ...getSingleAttributeParams } = params;
        const data = await getSingleAttributeApi(getSingleAttributeParams, mode);
        if (!Array.isArray(data.attr_vals)) {
          if (getSingleAttributeParams.attr_sel == 'many') {
            data.attr_vals = data.attr_vals.split(',');
          }
          if (getSingleAttributeParams.attr_sel == 'only') {
            data.attr_vals = data.attr_vals.split(' ');
          }
        }
        return data;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /**
     * @description: delete attributes
     */
    async deleteAttributes(
      params: deleteAttributesParams & { mode?: ErrorMessageMode },
    ): Promise<void> {
      try {
        const { mode, ...deleteAttributesParams } = params;
        await deleteAttributesApi(deleteAttributesParams, mode);
      } catch (error) {
        return Promise.reject(error);
      }
    },
  },
});
